import java.io.*;
import java.util.*;
import javax.script.*;

class RPN {
	static double lastResult;
	static String operationsDirectory = "operations";
	static File directory = new File(operationsDirectory);
	static ScriptEngineManager mgr = new ScriptEngineManager();
	static ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");

	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);
		RPNStack tokens = null;

		try {
			if (args.length == 1)
				tokens = (RPNStack)Class.forName(args[0]).newInstance();
			else
				tokens = new MyStack();
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		while (true) {
			System.out.print(">>> ");
			String expression = reader.nextLine();
			
			if (expression.equals("exit")) System.exit(0);
			
			try {
				System.out.println(evalExpression(expression, tokens));
			}
			catch (Exception e) {
				System.out.println("Erro");
				System.out.println("Detalhes: " + e.getMessage());
			}
			tokens.clear();
		}
	}
	
	static double evalExpression(String expression, RPNStack tokens) throws Exception {
		for (String token : expression.split(" ")) {
			try {
				if (token.equals("_"))
					tokens.push(lastResult);
				else {
					double operand = Double.parseDouble(token);
					tokens.push(operand);
				}
			}
			catch (Exception e) {
				evalOperation(token, tokens);
			}
		}
		lastResult = tokens.pop();
		return lastResult;
	}
	
	static void evalOperation(String operator, RPNStack tokens) throws Exception {
		for (String fileName : directory.list()) {
			if (fileName.endsWith(".js")) {
				InputStream is = new RPN().getClass().getResourceAsStream(operationsDirectory + "/" + fileName);
				Reader rd = new InputStreamReader(is);

				try {
					jsEngine.eval(rd);

					if (jsEngine.get("operator").equals(operator)) {
						Invocable in = (Invocable)jsEngine;
						in.invokeFunction("execute", tokens);
						return;
					}
				}
				catch (Exception e) {
					throw new Exception("Parametros insuficientes");
				}
			}
		}
		throw new Exception("Operacao nao encontrada");
	}
}
